#include <gtk/gtk.h>

//创建程序功能包装结构
typedef struct {
	GtkWidget *window;
	GtkWidget *pbar;
	int timer;
}progress_data_t,*pprogress_data_t;

//计时器更新回调函数
gint progress_timeout(gpointer data){
	gfloat new_val = gtk_progress_get_value(GTK_PROGRESS(data)) + 1;
	GtkAdjustment *adj = GTK_PROGRESS(data)->adjustment;
	if(new_val > adj->upper) new_val = adj->lower;
	gtk_progress_set_value(GTK_PROGRESS(data),new_val);
	return TRUE;
}

void toggle_show_text(GtkWidget *self,pprogress_data_t pdata){
	gtk_progress_set_show_text(GTK_PROGRESS(pdata->pbar),
		GTK_TOGGLE_BUTTON(self)->active);
}

void toggle_activity_mode(GtkWidget *self,pprogress_data_t pdata){
	gtk_progress_set_activity_mode(GTK_PROGRESS(pdata->pbar),
		GTK_TOGGLE_BUTTON(self)->active);
}

void set_continuous_mode(GtkWidget *self,pprogress_data_t pdata){
	gtk_progress_bar_set_bar_style(GTK_PROGRESS_BAR(pdata->pbar),
		GTK_PROGRESS_CONTINUOUS);
}

void set_discrete_mode(GtkWidget *self,pprogress_data_t pdata){
	gtk_progress_bar_set_bar_style(GTK_PROGRESS_BAR(pdata->pbar),
		GTK_PROGRESS_DISCRETE);
}

void destroy_progress(GtkWidget *self,pprogress_data_t pdata){
	gtk_timeout_remove(pdata->timer);
	pdata->timer = 0;
	pdata->window = NULL;
	g_free(pdata);
	gtk_main_quit();
}

int main(int argc,char **argv){
	pprogress_data_t pdata;
	GtkWidget *align,*separator,*table,*button,*check,*vbox;
	GtkAdjustment *adj;

	gtk_init(&argc,&argv);
	pdata = g_malloc(sizeof(progress_data_t));
	pdata->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_policy(GTK_WINDOW(pdata->window),FALSE,FALSE,TRUE);
	gtk_signal_connect(GTK_OBJECT(pdata->window),"destroy",GTK_SIGNAL_FUNC(
		destroy_progress),pdata);
	gtk_window_set_title(GTK_WINDOW(pdata->window),"GtkProgressBar");
	gtk_container_set_border_width(GTK_CONTAINER(pdata->window),0);
	vbox = gtk_vbox_new(FALSE,5);
	gtk_container_set_border_width(GTK_CONTAINER(vbox),10);
	gtk_container_add(GTK_CONTAINER(pdata->window),vbox);
	
	align = gtk_alignment_new(0.5,0.5,0,0);
	gtk_box_pack_start(GTK_BOX(vbox),align,FALSE,FALSE,5);

	adj = (GtkAdjustment *)gtk_adjustment_new(0,1,150,0,0,0);
	pdata->pbar = gtk_progress_bar_new_with_adjustment(adj);
	gtk_progress_bar_set_discrete_blocks(GTK_PROGRESS_BAR(pdata->pbar),50);
	gtk_widget_set_size_request(GTK_WIDGET(pdata->pbar),300,20);

	gtk_progress_set_format_string(GTK_PROGRESS(pdata->pbar),
		"%v from [%l-%u] (=%p%%)");
	gtk_container_add(GTK_CONTAINER(align),pdata->pbar);

	pdata->timer = gtk_timeout_add(100,progress_timeout,pdata->pbar);
	separator = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(vbox),separator,FALSE,FALSE,0);

	table = gtk_table_new(2,3,FALSE);
	gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,TRUE,0);

	check = gtk_check_button_new_with_label("Show text");
	gtk_table_attach(GTK_TABLE(table),check,0,1,0,1,
		GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,5,5);
	gtk_signal_connect(GTK_OBJECT(check),"clicked",GTK_SIGNAL_FUNC(toggle_show_text),pdata);

	check = gtk_check_button_new_with_label("Activity mode");
	gtk_table_attach(GTK_TABLE(table),check,0,1,1,2,
		GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,5,5);
	gtk_signal_connect(GTK_OBJECT(check),"clicked",GTK_SIGNAL_FUNC(toggle_activity_mode),pdata);

	separator = gtk_vseparator_new();
	gtk_table_attach(GTK_TABLE(table),separator,1,2,0,2,
		GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,5,5);

	button = gtk_radio_button_new_with_label(NULL,"Continuous");
	gtk_table_attach(GTK_TABLE(table),button,2,3,0,1,
		GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,5,5);
	gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(set_continuous_mode),
		pdata);
	button = gtk_radio_button_new_with_label(gtk_radio_button_group(
		GTK_RADIO_BUTTON(button)),"Discrete");
	gtk_table_attach(GTK_TABLE(table),button,2,3,1,2,
		GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,5,5);
	gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(set_discrete_mode),
		pdata);
	separator = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(vbox),separator,FALSE,FALSE,0);
	button = gtk_button_new_with_label("close");
	gtk_signal_connect_object(GTK_OBJECT(button),"clicked",(GtkSignalFunc)gtk_widget_destroy,
		GTK_OBJECT(pdata->window));
	gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0);
	GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
	gtk_widget_grab_default(button);
	gtk_widget_show_all(pdata->window);
	gtk_main();

	return 0;
}